home *** CD-ROM | disk | FTP | other *** search
- Path: lade.news.pipex.net!pipex!dircon!usenet
- From: sridgway@dircon.co.uk (Steven Ridgway)
- Newsgroups: comp.lang.c
- Subject: Re: passing arrays and returning structs
- Date: Mon, 11 Mar 1996 21:50:44 GMT
- Organization: Direct Connection
- Message-ID: <4i27eo$202@newsgate.dircon.co.uk>
- References: <4i2128$69d@news2.acs.oakland.edu>
- NNTP-Posting-Host: gw4-129.pool.dircon.co.uk
- X-Newsreader: Forte Free Agent 1.0.82
-
- jggoslin@vela.acs.oakland.edu (Monument) wrote:
-
- >I have been wracking my brains over this one. I needed to write a
- >program to do the transitive closure of a binary relation matrix, no
- >problems encountered during that. However, I tried to streamline the
- >code, by putting the transitive closure algorithm in it's own
- >function. When I did this, I tried to pass the initially read in
- >matrix into the function as an argument, and return a message buffer
- >to the calling function.
-
- >I got a mess of errors, included below for your perusal. If anyone
- >has any suggestions on how I could get the pointers and returns fixed,
- >I would sincerely appreciate it. Post or email, since I read both
- >regularly.
-
- >===client.h===
- >#include <stdio.h>
- >#include <sys/errno.h>
- >#include <sys/ipc.h>
- >#include <sys/msg.h>
- >#include <sys/types.h>
-
- >#define PATH "./server"
- >#define PROJ 'B'
- >#define PERMS 0666
- >#define MAXSZ 200
-
- >key_t key;
- >int msgqid;
-
- >typedef struct my_msgbuf {
- > long mtype;
- > int pid;
- > int size;
- > int data[2*MAXSZ];
- >} Message;
- >===client.h===
-
- >===client.c===
- >// header files
- >#include "client.h"
-
- >// function prototypes
- >struct Message transitive_closure(int matrix[]);
-
- >// MAINLINE
- >int main(int argc, char *argv[])
- >{
- >[I am going to delete a bunch of code here that is irrelevant to the
- >problem, since I know it works. All the code I delete does is reads
- >in the matrix]
-
- >[here is the relevant call]
- > // get the transitive closure
- > buffer = transitive_closure(matrix);
-
- > // print out results
- > puts("Transitive Closure:");
- > for (i=0; i<buffer.size; i++)
- > {
- > for (j=0; j<buffer.size; j++)
- > printf(" %d", buffer.data[i*buffer.size+j]);
- > printf("\n");
- > }
-
- > // successful finish
- > return 0;
- >}
-
- >struct Message* transitive_closure(int matrix[])
- >{
- > int i, j, size;
- > Message buffer;
- > pid_t pid;
-
- >[here do I refer to the subtypes in the correct manner? "." vs. "->"
- >is what I'm talking about]
-
- > buffer.mtype=1L;
- > buffer.pid=pid;
- > buffer.size=size;
- > for (i=0; i<size; i++)
- > for (j=0; j<size; j++)
- > buffer.data[i*size+j]=matrix[i*size+j];
-
- >[is the return type correct?]
- > return *buffer;
- >}
- >===client.c===
-
- >===ERRORS===
- >cc -g -c client.c
- >/usr/lib/cmplrs/cc/cfe: Error: client.c, line 58: Functions cannot return a non-object type
- > buffer = transitive_closure(matrix);
- > ---------------------------^
- >/usr/lib/cmplrs/cc/cfe: Error: client.c, line 58: Reference an expression of void type or an incomplete type.
- > buffer = transitive_closure(matrix);
- > ---------------------------^
- >/usr/lib/cmplrs/cc/cfe: Error: client.c, line 73: redeclaration of 'transitive_closure'; previous declaration at line 11 in file 'client.c'
- > struct Message* transitive_closure(int matrix[])
- > ----------------^
- >/usr/lib/cmplrs/cc/cfe: Error: client.c, line 73: Incompatible function return type for this function
- > struct Message* transitive_closure(int matrix[])
- > ----------------------------------^
- >/usr/lib/cmplrs/cc/cfe: Error: client.c, line 109: Dereference a non-pointer
- > return *buffer;
- > --------^
- >*** Exit 1
- >Stop.
- >===ERRORS===
-
- > ----------------------------------------------------------------------------
- >| Jeff Goslin - Monument | "Oh Bentson, you are so |
- >| jggoslin@vela.acs.oakland.edu | mercifully free from the |
- >| | ravages of intellect." |
- >| http://www.acs.oakland.edu/links/jggoslin | --Evil, The Time Bandits |
- > ----------------------------------------------------------------------------
- >| how come everyone elses religion is a cult but your cult is a religion |
- > ----------------------------------------------------------------------------
-
- Hi,
-
- You have at least three problems here.
-
- 1. You should prototype your function transitive_closure before
- you use it. ie add the line :
- struct Message* transitive_closure(int matrix[]);
- at the top of your file or in a header (before you reference it but
- after you define Message anyway).
- Without this the compiler assumes it returns int, then whines when you
- define it as something else.
-
- 2. Your return in transistive_matrix is screwed up. If you want
- to return a pointer to a Message (as your function definition implies)
- you should use &buffer not *buffer. However this will not solve
- everything as there is a more subtle problem ...
-
- 3. In transitive_matrix you are trying to return a pointer to a
- Message, however your buffer variable is a local variable, ie it
- exists only during the scope of that function. If you return a pointer
- to your local variable you will be returning a pointer to some random
- place on the stack, which will be overwritten by other things. If you
- really need to return a Message, you can either :
- a. Change the function to return a Message direct (ie a structure).
- This will work, but is not a good idea as you are copying a lot of
- data on and off the stack.
- b. Dynamically allocate a Message within transistive_matrix (ie
- Message *buffer = malloc(sizeof(Message)); ) then return that.
- However you then have to be carefull that you free it explicitly at
- the appropriate time.
- c. Make buffer a static variable of transitive_matrix. Thus the memory
- for buffer is permanent and you can throw pointers to it around as you
- like. The very serious disadvantage to this is that there is only one
- Message around at any one time. Thus if you want to call
- transitive_matrix lots of times, and compare the resultant messages
- you will be stuffed.
- d. Change transitive_matrix so that instead of returning a Message, it
- takes a pointer to one as another argument. It is then up to the
- caller to get allocate (dynamically or on the stack) a Message. This
- sort of problem happens again and again in big C programs, and in my
- experience option d. works is the best.
-
- Hope this help.
-
- Steven Ridgway (sridgway@dircon.co.uk)
-
-